package db

import (
	"database/sql/driver"
	"encoding/json"
	"errors"
	"fmt"
	"time"
)

const CurrentTimeStamp = "2006-01-02 15:04:05"

type Time time.Time

func (t *Time) Scan(value interface{}) error {
	var err error
	if t2, ok := value.(time.Time); ok {
		*t = Time(t2)
	} else {
		var tm time.Time
		switch v := value.(type) {
		case string:
			tm, err = time.Parse(CurrentTimeStamp, v)
		case []byte:
			tm, err = time.Parse(CurrentTimeStamp, string(v))
		default:
			err = errors.New("invalid type for current_timestamp")
		}
		*t = Time(tm)
	}
	return err
}

func (t Time) Value() (driver.Value, error) {
	return time.Time(t), nil
}
func (t *Time) Format(layout string) string {
	return time.Time(*t).Format(layout)
}
func (t *Time) UnmarshalJSON(v []byte) error {
	if len(v) < 2 || v[0] != '"' || v[len(v)-1] != '"' {
		return nil
	}
	var err error
	var tm time.Time
	tm, err = time.Parse(CurrentTimeStamp, string(v[1:len(v)-1]))
	*t = Time(tm)
	return err
}

func (t *Time) MarshalJSON() ([]byte, error) {
	var tm = time.Time(*t)
	b := make([]byte, 0, len(CurrentTimeStamp)+2)
	b = append(b, '"')
	b = tm.AppendFormat(b, CurrentTimeStamp)
	b = append(b, '"')
	return b, nil
}

type SSJson map[string]string

func (j *SSJson) GormDataType() string {
	return "text"
}

func (j *SSJson) Scan(value interface{}) (err error) {
	switch value.(type) {
	case []byte:
		*j = make(map[string]string)
		err = json.Unmarshal(value.([]byte), j)
	case string:
		*j = make(map[string]string)
		err = json.Unmarshal([]byte(value.(string)), j)
	default:
		err = errors.New(fmt.Sprint("Failed to unmarshal JSONB value:", value))
	}

	return err
}

func (j *SSJson) Value() (driver.Value, error) {
	if len(*j) == 0 {
		return nil, nil
	}
	return json.Marshal(j)
}
